package com.wuhunyu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wuhunyu.client.ServiceUserClient;
import com.wuhunyu.commonutils.check.Check;
import com.wuhunyu.commonutils.result.CommonResult;
import com.wuhunyu.entities.StatisticsDaily;
import com.wuhunyu.mapper.StatisticsDailyMapper;
import com.wuhunyu.query.DataQuery;
import com.wuhunyu.service.StatisticsDailyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wuhunyu.servicebase.exception.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 网站统计日数据 服务实现类
 * </p>
 *
 * @author wuhunyu
 * @since 2021-01-27
 */
@Service("statisticsDailyService")
public class StatisticsDailyServiceImpl extends ServiceImpl<StatisticsDailyMapper, StatisticsDaily> implements StatisticsDailyService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private ServiceUserClient serviceUserClient;

    @Resource
    private StatisticsDailyMapper statisticsDailyMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult countUser(Date date) {
        // 获取注册人数
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = dateFormat.format(new Date());
        // 查询数据库中是否存在数据
        QueryWrapper<StatisticsDaily> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("date_calculated", dateStr);
        Assert.isRight(statisticsDailyMapper.selectCount(queryWrapper) != 0, "该日期已统计");
        // 依次取出登录数，新增课程数和视频播放数
        int login = 0;
        int course = 0;
        int play = 0;
        // login
        if (redisTemplate.opsForValue().get("login") == null) {
            login = 0;
        } else {
            login = Integer.parseInt(redisTemplate.opsForValue().get("login"));
        }
        // course
        if (redisTemplate.opsForValue().get("course") == null) {
            course = 0;
        } else {
            course = Integer.parseInt(redisTemplate.opsForValue().get("course"));
        }
        // play
        if (redisTemplate.opsForValue().get("play") == null) {
            play = 0;
        } else {
            play = Integer.parseInt(redisTemplate.opsForValue().get("play"));
        }
        CommonResult commonResult = serviceUserClient.countRegister(dateStr);
        Assert.isRight(Check.isBlank(commonResult)
                || Check.isBlank(commonResult.getData())
                || Check.isBlank(commonResult.getData().get("register")), "获取注册人数失败");
        int register = (int) commonResult.getData().get("register");
        // 执行插入操作
        StatisticsDaily data = new StatisticsDaily(
                null,
                dateStr,
                register,
                login,
                play,
                course,
                null,
                null
        );
        Assert.isRight(statisticsDailyMapper.insert(data) != 1, "统计用户信息失败");
        return CommonResult.success("统计用户信息成功");
    }

    @Override
    public CommonResult showData(DataQuery dataQuery) {
        // 校验参数
        Assert.isRight(Check.isBlank(dataQuery), "查询对象不能为空");
        // 查询对象类型不能为空
        Assert.isRight(Check.isBlank(dataQuery.getType()), "查询统计类型不能为空");
        // 执行查询操作
        QueryWrapper<StatisticsDaily> queryWrapper = new QueryWrapper<>();
        queryWrapper.le(Check.isNotBlank(dataQuery.getBegin()), "gmt_create", dataQuery.getBegin());
        queryWrapper.le(Check.isNotBlank(dataQuery.getEnd()), "gmt_create", dataQuery.getEnd());
        queryWrapper.select(dataQuery.getType(), "gmt_create");
        queryWrapper.orderByAsc("gmt_create");
        List<StatisticsDaily> statisticsDailies = statisticsDailyMapper.selectList(queryWrapper);
        ArrayList<String> dates = new ArrayList<>();
        ArrayList<Integer> nums = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        switch (dataQuery.getType()) {
            case "register_num":
                statisticsDailies.forEach(obj -> {
                    dates.add(dateFormat.format(obj.getGmtCreate()));
                    nums.add(obj.getRegisterNum());
                });
                break;
            case "login_num":
                statisticsDailies.forEach(obj -> {
                    dates.add(dateFormat.format(obj.getGmtCreate()));
                    nums.add(obj.getLoginNum());
                });
                break;
            case "video_view_num":
                statisticsDailies.forEach(obj -> {
                    dates.add(dateFormat.format(obj.getGmtCreate()));
                    nums.add(obj.getVideoViewNum());
                });
                break;
            case "course_num":
                statisticsDailies.forEach(obj -> {
                    dates.add(dateFormat.format(obj.getGmtCreate()));
                    nums.add(obj.getCourseNum());
                });
                break;
            default:
                // 直接报错
                Assert.isRight(true, "查询统计类型非法");
                break;
        }
        // 封装数据
        Map<String, Object> map = new HashMap<>(16);
        map.put("dates", dates);
        map.put("nums", nums);
        return CommonResult.success("查询统计用户信息成功", map);
    }
}
